﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net.Http;
using HtmlAgilityPack;

namespace HW7_2NumberCrawler
{
    public partial class Form1 : Form
    {
        private HashSet<string> _urls = new HashSet<string>();
        private HashSet<string> _phoneNumbers = new HashSet<string>();

        public Form1()
        {
            InitializeComponent();
        }

        private async void button1_Click(object sender, EventArgs e)
        {
            // 获取用户输入的关键词
            string keyword = textBox1.Text;

            // 构造搜索引擎的URL
            string url = "https://www.baidu.com/s?wd=" + keyword;

            // 创建HttpClient对象，发送GET请求，获取搜索结果页面内容
            HttpClient httpClient = new HttpClient();
            HttpResponseMessage response = await httpClient.GetAsync(url);
            string responseBody = await response.Content.ReadAsStringAsync();

            // 使用HtmlAgilityPack解析搜索结果页面
            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(responseBody);

            // 获取所有的a标签的href属性
            var hrefs = doc.DocumentNode.Descendants("a")
                .Select(a => a.GetAttributeValue("href", ""))
                .Where(href => !string.IsNullOrEmpty(href));

            // 定义正则表达式
            Regex phoneRegex = new Regex(@"((\d{3,4}-)?\d{7,8})");

            // 定义任务列表
            List<Task> tasks = new List<Task>();

            // 并行处理每个链接
            var hrefTasks = hrefs.Select(async href =>
            {
                // 判断是否是URL
                Uri uriResult;
                bool isUrl = Uri.TryCreate(href, UriKind.Absolute, out uriResult)
                    && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps);

                if (isUrl)
                {
                    // 创建HttpClient对象，发送GET请求，获取链接页面内容
                    HttpResponseMessage pageResponse = await httpClient.GetAsync(href);
                    string pageResponseBody = await pageResponse.Content.ReadAsStringAsync();

                    // 使用HtmlAgilityPack解析链接页面
                    HtmlAgilityPack.HtmlDocument pageDoc = new HtmlAgilityPack.HtmlDocument();
                    pageDoc.LoadHtml(pageResponseBody);

                    // 查找页面中所有的电话号码
                    var phoneNumbers = pageDoc.DocumentNode.DescendantsAndSelf()
                        .Select(node => node.InnerText)
                        .Where(text => phoneRegex.IsMatch(text))
                        .Select(text => phoneRegex.Match(text).Value);

                    // 添加电话号码和链接
                    foreach (var phoneNumber in phoneNumbers)
                    {
                        lock (_phoneNumbers)
                        {
                            if (!_phoneNumbers.Contains(phoneNumber))
                            {
                                _phoneNumbers.Add(phoneNumber);
                                textBox3.Invoke(new Action(() => textBox3.AppendText(phoneNumber + Environment.NewLine)));
                            }
                        }
                    }

                    lock (_urls)
                    {
                        if (!_urls.Contains(href))
                        {
                            _urls.Add(href);
                            listBox1.Invoke(new Action(() => listBox1.Items.Add(href)));
                        }
                    }
                }
            });

            // 等待所有任务完成
            await Task.WhenAll(hrefTasks);

            foreach (var phoneNumber in _phoneNumbers)
            {
                textBox3.AppendText(phoneNumber + Environment.NewLine);
            }

            foreach (var url1 in _urls)
            {
                listBox1.Items.Add(url1);
            }

            // 更新爬虫结果
            UpdateResult();
        }

        private void ParseHtml(string html)
        {
            // 使用HtmlAgilityPack解析搜索结果页面
            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(html);

            // 查找所有的a标签
            HtmlNodeCollection nodes = doc.DocumentNode.SelectNodes("//a[@href]");
            if (nodes != null)
            {
                foreach (HtmlNode link in nodes)
                {
                    // 获取a标签中的href属性
                    string href = link.GetAttributeValue("href", "");
                    if (!string.IsNullOrEmpty(href))
                    {
                        // 判断是否是电话号码
                        Regex phoneRegex = new Regex(@"((\d{3,4}-)?\d{7,8})");
                        if (phoneRegex.IsMatch(href))
                        {
                            string phoneNumber = phoneRegex.Match(href).Value;
                            if (!_phoneNumbers.Contains(phoneNumber))
                            {
                                _phoneNumbers.Add(phoneNumber);
                                textBox3.AppendText(phoneNumber + Environment.NewLine);
                            }
                        }
                        else
                        {
                            // 判断是否是URL
                            Uri uriResult;
                            bool isUrl = Uri.TryCreate(href, UriKind.Absolute, out uriResult)
                                && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps);

                            if (isUrl)
                            {
                                if (!_urls.Contains(href))
                                {
                                    _urls.Add(href);
                                    listBox1.Items.Add(href);
                                }
                            }
                        }
                    }
                }
            }
        }

        private void UpdateResult()
        {
            listBox1.Items.Clear();
            foreach (var url in _urls)
            {
                listBox1.Items.Add(url);
            }

            listBox1.Items.Add("电话号码：");
            foreach (var phoneNumber in _phoneNumbers)
            {
                listBox1.Items.Add(phoneNumber);
            }
        }

        private void textBox3_TextChanged(object sender, EventArgs e)
        {

        }

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void textBox2_TextChanged(object sender, EventArgs e)
        {

        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }
    }
}
